package com.ftg.learn.rbac.service.impl;

import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonBooleanFormatVisitor;
import com.ftg.learn.rbac.entity.Permission;
import com.ftg.learn.rbac.mapper.PermissionMapper;
import com.ftg.learn.rbac.service.IPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kangjx
 * @since 2022-03-23
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {

    @Override
    public boolean updateForName(int id, String title) {
        return this.baseMapper.updateForName(id,title);
    }

    @Override
    public JSONObject showPermissionTree(int rid) {
        JSONObject json = new JSONObject();
        List<Permission> oldAll =this.baseMapper.selectList(null);
        JSONArray list = null;
        List<Integer> myself = this.baseMapper.showMyself(rid);
        try {
            list = this.toplevel(oldAll,-1,myself);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        //生成我有的数据
        try {
            json.put("allinfo",list);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }

    //事务在生产级别当中一定要添加
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveForPermission(int rid, List<Integer> pids) {
        //删除中间表里当前是用户的全部角色 信息
        super.baseMapper.deleteRolePermission(rid);

        //重新添加中间表里面的全部角色
        for (int i = 0; i < pids.size(); i++) {
            super.baseMapper.saveUserRole(rid,pids.get(i));
        }
        return true;
    }

    /**
     * 生成当前数据的最外层，为了完成与前台格式的相对应
     *     递归   ：  当某一个方法  对这个方法进行了调用的时候，我们把这种调用方式叫递归
     * @param list       数据库里面查询出来的数据格式
     * @param startid    最顶元素的parent_id  从-1开始
     * @param plist 所有子项
     * @return
     * @throws JSONException
     */
    private JSONArray toplevel(List<Permission> list, int startid,List<Integer> plist) throws JSONException {
        JSONArray firstlv = new JSONArray();

        for (Permission p : list) {
            if(p.getParentId() == startid){
                JSONObject obj = new JSONObject();

                // 生成相当于前面页面的对象格式
                obj.put("id",p.getId());  // 编号
                obj.put("title",p.getTitle());  //名称
                obj.put("checked",plist.contains(p.getId()) && p.getIsleaf()==1);
                firstlv.put(obj);
                obj.put("children",toplevel(list,p.getId(),plist)); //子元素
            }
        }
        return firstlv;
    }

}
